package ve.usb.crm;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;

import ve.usb.cohesion.runtime.CohesionAction;

import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.Transaction;
import ve.usb.cohesion.runtime.HibernateUtil;
import ve.usb.crm.hibernate.*;

import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import org.json.JSONStringer;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import java.awt.Color;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Calendar;
import javax.activation.MimetypesFileTypeMap;

/**
 * 
 */
public class AccionesFacturacion extends CohesionAction {

    /**
     * Called by Struts for the execution of action APreFacturacion.
     * 
     * @param mapping The ActionMapping used to select this instance.
     * @param form The optional ActionForm bean for this request.
     * @param request The HTTP Request we are processing.
     * @param response The HTTP Response we are processing.
     * @return The Struts name of the following step.
     * @throws java.lang.Exception For untreated exceptions. 
     * These exceptios will normally be treated with 
     * the default exception action.
     */
    public ActionForward APreFacturacion(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {

        //Salidas
        final String[] SALIDAS = {"VFacturacion",};
        final int SALIDA_0 = 0;

        int salida = SALIDA_0;
//Checking for actors administrador, empleado
        if (!CohesionActor.checkActor(request, 5)) {

            return mapping.findForward(CohesionActor.SALIDA_ACTOR);
        }
        Session s = HibernateUtil.getCurrentSession();
        Transaction tr = s.beginTransaction();
        try {
            FFacturacion fFacturacion = FFacturacion.clear(mapping, request);


            tr.commit();

        } catch (Exception ex) {
            tr.rollback();
            throw ex;
        } finally {
            try {
                s.close();
            } catch (Exception ex2) {
            }
        }
        return mapping.findForward(SALIDAS[salida]);
    }

    /**
     * Called by Struts for the execution of action AFacturacion.
     * 
     * @param mapping The ActionMapping used to select this instance.
     * @param form The optional ActionForm bean for this request.
     * @param request The HTTP Request we are processing.
     * @param response The HTTP Response we are processing.
     * @return The Struts name of the following step.
     * @throws java.lang.Exception For untreated exceptions. 
     * These exceptios will normally be treated with 
     * the default exception action.
     */
    public ActionForward AFacturacion(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {

        //Salidas
        final String[] SALIDAS = {"APreFactura", "VFacturacion",};
        final int SALIDA_0 = 0;
        final int SALIDA_1 = 1;

        int salida = SALIDA_0;
        Session s = HibernateUtil.getCurrentSession();
        Transaction tr = s.beginTransaction();
        try {
            FFacturacion fFacturacion = (FFacturacion) form;


            //Saco los productos de el request

            String msgError = "<span class='ui-icon ui-icon-alert' style='float: left;'></span> Alert: <div>";
            Boolean ahiError = false;
            List<ProductosCantidad> L_Productos = new ArrayList<ProductosCantidad>();
            Enumeration<String> nombres = request.getParameterNames();
            Pattern patron = Pattern.compile("cantidad_\\d+");
            List<String> cantidades = new ArrayList<String>();
            while (nombres.hasMoreElements()) {
                String tmp = nombres.nextElement();
                Matcher match = patron.matcher(tmp);

                if (match.find()) {
                    cantidades.add(tmp);
                }
            }

            String size = "cantidad_";
            boolean error = false;
            for (Iterator<String> it = cantidades.iterator(); it.hasNext();) {
                String string = it.next();
                int cantidad = Integer.parseInt(request.getParameter(string));
                Long catalogo = Long.parseLong(string.substring(size.length(), string.length()));

                Catalogo producto = (Catalogo) s.load(Catalogo.class, catalogo);
                ProductosCantidad prodC = new ProductosCantidad();
                prodC.setProducto(producto);
                prodC.setCantidad(cantidad);
                L_Productos.add(prodC);
                if (producto.getCantidad() < cantidad) {
                    error = true;
                    request.setAttribute("producto_" + producto.getIdCatalogo() + "Error", "Ahi un error en la cantidad");
                }

            }

            //Manejo de Errores
            //Error de cantidad
            if (error) {
                msgError += "Algun producto tiene mayor cantidad que la disponible<br>";
                ahiError = true;

            }

            if (cantidades.size() == 0) {
                msgError += "Es necesario ingresar un producto<br>";
                ahiError = true;
            }


            //Error de Nombre Vacio
            if (fFacturacion.getNombre().compareTo("") == 0) {
                msgError += "El nombre es requerido<br>";
                ahiError = true;
                request.setAttribute("nombreError", "<span class='ui-icon ui-icon-alert' style='float: left; margin-right: .3em;'></span>El nombre es requerido");
            }

            //Error de rif o cedula
            if (fFacturacion.getRifCedula().compareTo("") == 0) {
                msgError += "El rif es un campo requerido<br>";
                ahiError = true;
                request.setAttribute("rifError", "<span class='ui-icon ui-icon-alert' style='float: left; margin-right: .3em;'></span>El Rif es un campo requerido");
            }

            //Error de Ciudad
            if (fFacturacion.getCiudad().compareTo("") == 0) {
                msgError += "La cudad es requerida es requerido<br>";
                ahiError = true;
                request.setAttribute("ciudadError", "<span class='ui-icon ui-icon-alert' style='float: left; margin-right: .3em;'></span>Es un campo requerido es requerido");
            }

            //Error de Codigo Postal
            if (fFacturacion.getCodigoPostal().compareTo("") == 0) {
                msgError += "El Codigo Postal es requerido<br>";
                ahiError = true;
                request.setAttribute("codigoPostalError", "<span class='ui-icon ui-icon-alert' style='float: left; margin-right: .3em;'></span>Es un campo requerido");
            }
            //Error de Direccion
            if (fFacturacion.getDireccion().compareTo("") == 0) {
                msgError += "La direccion es requerido<br>";
                ahiError = true;
                request.setAttribute("direccionError", "<span class='ui-icon ui-icon-alert' style='float: left; margin-right: .3em;'></span>La Direccion es requerida");
            }


            if (ahiError) {
                msgError += "</div>";
                request.setAttribute("msg", msgError);
                request.setAttribute("L_Productos", L_Productos);
                salida = SALIDA_1;
            } else {

                //            Genero la factura

                Factura factura = new Factura();

                factura.setDireccion(fFacturacion.getDireccion());
                factura.setNombre(fFacturacion.getNombre());
                factura.setRazonSocial(fFacturacion.getRazon_Social());
                factura.setRifCedula(fFacturacion.getRifCedula());
                factura.setTelefono(fFacturacion.getTelefono());
                factura.setCiudad(fFacturacion.getCiudad());
                factura.setCodigoPostal(fFacturacion.getCodigoPostal());

                s.save(factura);
                s.flush();

                float monto = 0;
                float iva = 0;

                for (Iterator<String> it = cantidades.iterator(); it.hasNext();) {
                    String string = it.next();
                    int cantidad = Integer.parseInt(request.getParameter(string));
                    Long catalogo = Long.parseLong(string.substring(size.length(), string.length()));
                    FacturaCatalogo productoFactura = new FacturaCatalogo();

                    Catalogo producto = (Catalogo) s.load(Catalogo.class, catalogo);
                    productoFactura.setCantidad(cantidad);
                    productoFactura.setIdCatalogo(producto);
                    productoFactura.setIdFactura(factura);

                    s.save(productoFactura);
                    s.flush();

                    producto.setCantidad(producto.getCantidad() - cantidad);
                    s.save(producto);
                    s.flush();

                    float montoAct = (float) (producto.getCosto() * cantidad);
                    monto += montoAct;
                    float impuesto = (float) (producto.getImpuesto() / 100.0f);
                    iva += (float) (montoAct * impuesto);
                }


                factura.setMonto(monto);
                factura.setIva(iva);
                s.update(factura);
                s.flush();

                request.setAttribute("idFactura", factura.getIdFactura());
            }




            tr.commit();

        } catch (Exception ex) {
            tr.rollback();
            throw ex;
        } finally {
            try {
                s.close();
            } catch (Exception ex2) {
            }
        }
        return mapping.findForward(SALIDAS[salida]);
    }

    /**
     * Called by Struts for the execution of action APreFactura.
     * 
     * @param mapping The ActionMapping used to select this instance.
     * @param form The optional ActionForm bean for this request.
     * @param request The HTTP Request we are processing.
     * @param response The HTTP Response we are processing.
     * @return The Struts name of the following step.
     * @throws java.lang.Exception For untreated exceptions. 
     * These exceptios will normally be treated with 
     * the default exception action.
     */
    public ActionForward APreFactura(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {

        //Salidas
        final String[] SALIDAS = {"VFactura",};
        final int SALIDA_0 = 0;

        int salida = SALIDA_0;
        Session s = HibernateUtil.getCurrentSession();
        Transaction tr = s.beginTransaction();
        try {
            //Obtengo el id cde la cuenta del request asi este como atributo o como parametro
            Long idFactura = (Long) request.getAttribute("idFactura");
            if (idFactura == null) {
                idFactura = lookup_Long(request, "idFactura");
            }

            //Saco la factura de la base de datos
            Factura factura = (Factura) s.createQuery("from Factura "
                    + "where idFactura = :idfactura").setLong("idfac"
                    + "tura", idFactura).uniqueResult();

            List<FacturaCatalogo> productos = (List<FacturaCatalogo>) s.createQuery("from FacturaCatalogo where idFactura = "
                    + ":idfactura").setLong("idfactura", idFactura).list();

            for (Iterator<FacturaCatalogo> it = productos.iterator(); it.hasNext();) {
                FacturaCatalogo facturaCatalogo = it.next();
                Hibernate.initialize(facturaCatalogo.getIdCatalogo());
            }

            request.setAttribute("factura", factura);
            request.setAttribute("productos", productos);

            tr.commit();

        } catch (Exception ex) {
            tr.rollback();
            throw ex;
        } finally {
            try {
                s.close();
            } catch (Exception ex2) {
            }
        }
        return mapping.findForward(SALIDAS[salida]);
    }

    /**
     * Called by Struts for the execution of action AFormularioProducto.
     * 
     * @param mapping The ActionMapping used to select this instance.
     * @param form The optional ActionForm bean for this request.
     * @param request The HTTP Request we are processing.
     * @param response The HTTP Response we are processing.
     * @return The Struts name of the following step.
     * @throws java.lang.Exception For untreated exceptions. 
     * These exceptios will normally be treated with 
     * the default exception action.
     */
    public ActionForward AFormularioProducto(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {

        //Salidas
        final String[] SALIDAS = {"VFormularioProducto",};
        final int SALIDA_0 = 0;

        int salida = SALIDA_0;
        Session s = HibernateUtil.getCurrentSession();
        Transaction tr = s.beginTransaction();
        try {
            Long tmp = lookup_Long(request, "idProducto");
            Catalogo producto = new Catalogo();
            if (tmp == null) {
                producto.setIdCatalogo(500);
                producto.setNombre("no lo reconocio");
            } else {
                producto = (Catalogo) s.createQuery("from Catalogo where idCatalogo = :id").setLong("id", tmp).uniqueResult();
            }

            request.setAttribute("producto", producto);


            tr.commit();

        } catch (Exception ex) {
            tr.rollback();
            throw ex;
        } finally {
            try {
                s.close();
            } catch (Exception ex2) {
            }
        }
        return mapping.findForward(SALIDAS[salida]);
    }

    /**
     * Called by Struts for the execution of action AImprimirFactura.
     * 
     * @param mapping The ActionMapping used to select this instance.
     * @param form The optional ActionForm bean for this request.
     * @param request The HTTP Request we are processing.
     * @param response The HTTP Response we are processing.
     * @return The Struts name of the following step.
     * @throws java.lang.Exception For untreated exceptions. 
     * These exceptios will normally be treated with 
     * the default exception action.
     */
    public ActionForward AImprimirFactura(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {

        //Salidas
        final String[] SALIDAS = {"VFactura",};
        final int SALIDA_0 = 0;

        int salida = SALIDA_0;
        Session s = HibernateUtil.getCurrentSession();
        Transaction tr = s.beginTransaction();
        try {

            Long idFactura = (Long) lookup_Long(request, "idFactura");

            Factura factura = (Factura) s.load(Factura.class, idFactura);

            FacturaCatalogo a;


            List<FacturaCatalogo> productos = (List<FacturaCatalogo>) s.createQuery("from FacturaCatalogo where idFactura = "
                    + ":idfactura").setLong("idfactura", idFactura).list();

            for (Iterator<FacturaCatalogo> it = productos.iterator(); it.hasNext();) {
                FacturaCatalogo facturaCatalogo = it.next();

                Hibernate.initialize(facturaCatalogo.getIdCatalogo());
            }

//            File facturaPdf = GUARDAR_PDF(factura, productos);
//            String contentType = new MimetypesFileTypeMap().getContentType(facturaPdf);
//            String contentType = documento.getContentType();
//            File file          = new File(documento.getEnlace());
//
//            return new FileStreamInfo(contentType, facturaPdf);



        } catch (Exception ex) {
            tr.rollback();
            throw ex;
        } finally {
            try {
                s.close();
            } catch (Exception ex2) {
            }
        }
        return mapping.findForward(SALIDAS[salida]);
    }

    /**
     * Called by Struts for the execution of action APreFacturas.
     * 
     * @param mapping The ActionMapping used to select this instance.
     * @param form The optional ActionForm bean for this request.
     * @param request The HTTP Request we are processing.
     * @param response The HTTP Response we are processing.
     * @return The Struts name of the following step.
     * @throws java.lang.Exception For untreated exceptions. 
     * These exceptios will normally be treated with 
     * the default exception action.
     */
    public ActionForward APreFacturas(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {

        //Salidas
        final String[] SALIDAS = {"VFacturas",};
        final int SALIDA_0 = 0;

        int salida = SALIDA_0;
        Session s = HibernateUtil.getCurrentSession();
        Transaction tr = s.beginTransaction();
        try {

            List<Factura> list = (List<Factura>) s.createQuery("from Factura").list();

            Factura tmp = new Factura();





            request.setAttribute("L_Factura", list);



            tr.commit();

        } catch (Exception ex) {
            tr.rollback();
            throw ex;
        } finally {
            try {
                s.close();
            } catch (Exception ex2) {
            }
        }





        return mapping.findForward(SALIDAS[salida]);
    }
}
